package com.vvv.designpattern.adapter;

import com.alibaba.fastjson.JSONObject;
import com.vvv.designpattern.pojo.UserInfo;
import com.vvv.designpattern.service.UserService;
import com.vvv.designpattern.uilts.HttpClientUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;

/**
 * @author vvv
 * @date 2023-11-14 16 58
 * discription 第三方登录的适配器类
 *
 * 在不修改原有的逻辑下，对UserService进行扩展，复用UserService的方法
 * TODO 这里我们是让前端先直接去请求第三方认证，也就是clientId和state值是前端写死的
 *
 * TODO 我们可以让前端先去向后端请求clientId和state值，然后再直接去向第三方发认证
 *
 * 也就是说可以一直用token去获取gitee的用户信息
 */
@Component
public class Login3rdAdapter extends UserService implements Login3rdTarget {

    @Value("${gitee.state}")
    private String giteeState;
    @Value("${gitee.token.url}")
    private String giteeTokenUrl;
    @Value("${gitee.user.url}")
    private String giteeUserUrl;
    @Value("${gitee.user.prefix}")
    private String giteeUserPrefix;

    /**
     *
     * @param code code值是为请求登录的用户生成的，是唯一的
     * ，通过访问/oauth/authorize接口返回的，如果用重复的code值去发token请求，会被拒绝
     * @param state 随机生成的，用来保证回调接口不被恶意调用
     * @return
     */
    @Override
    public String loginByGitee(String code, String state) {
        // 1. 验证一下state值是否和后端的state值相同
        if (!giteeState.equals(state)) {
            throw new UnsupportedOperationException("Invaild state!");
        }
        // 2. 根据code请求token
        String tokenUrl = giteeTokenUrl.concat(code);
        JSONObject tokenResponse = HttpClientUtils.execute(tokenUrl, HttpMethod.POST);
        if (tokenResponse.get("error") != null) {
            throw new UnsupportedOperationException("Invaild state!");
        }


        String token = String.valueOf(tokenResponse.get("access_token"));
        // 3. 根据token请求用户信息、
        String userUrl = giteeUserUrl.concat(token);
        JSONObject userInfoResponse = HttpClientUtils.execute(userUrl, HttpMethod.GET);
        // 4. 设置用户名和密码
        String username = giteeUserPrefix.concat(String.valueOf(userInfoResponse.get("name")));
        String password = username;
        // 4. 登录和注册
        return this.autoRegister3rdAndLogin(username, password);
    }

    private String autoRegister3rdAndLogin(String username, String password) {
        // 1. 检查用户是否已经存在
        if (super.checkUserExists(username)) {
            // 1.1 存在直接登录
            return super.login(username, password);
        }
        // 2. 不存在创建UserInfo，先注册，在登录
        UserInfo userInfo = new UserInfo();
        userInfo.setUserName(username);
        userInfo.setUserPassword(password);
        super.register(userInfo);

        return super.login(username, password);
    }

    @Override
    public String loginByWechat(String... params) {
        return null;
    }

    @Override
    public String loginByQQ(String... params) {
        return null;
    }
}
